/*
** Copyright (c) 2009  Kimmo 'Rainy' Pekkola
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program.  If not, see http://www.gnu.org/licenses.
*/

#include "precompiled.h"
#include "numberitem.h"
#include "rotator.h"
#include "mainwindow.h"
#include "thememanager.h"

//-----------------------------------------------------------------------------
/**
** The constructor.
**
** \param pRotator Pointer to the rotator which contains this item.
** \param x The x offset of the item relative to the scene's origin.
** \param y The y offset of the item relative to the scene's origin.
** \param bSeparator If true this is a separator (:).
*/
CNumberItem::CNumberItem(CRotator* pRotator, int x, int y, bool bSeparator) : QGraphicsItem()
{
    m_W = bSeparator ? SEPARATOR_WIDTH : NUMBER_ITEM_WIDTH;
    m_H = NUMBER_ITEM_HEIGHT;
    m_Offset = QPoint(x, y);
    m_bSeparator = bSeparator;
    m_Value = 0;
    m_bShowBackground = false;
    m_bReflection = false;
    m_bDimmed = false;
    m_pRotator = pRotator;

    setPosition(0, 0);
}

//-----------------------------------------------------------------------------
/**
** The destructor.
*/
CNumberItem::~CNumberItem()
{
}

//-----------------------------------------------------------------------------
/**
** Sets the position for the item.
**
** \param pos The new position for the item.
*/
void CNumberItem::setPosition(int x, int y)
{
    m_Position = QPoint(x, y);
    setPos(QPoint(x, y) + m_Offset);
}

//-----------------------------------------------------------------------------
/**
** Sets the rotation adjustment for the item. The value is added to the original y-position.
**
** \param value The new offset value.
*/
void CNumberItem::setYAdjustment(int value)
{
    QPoint pos = m_Position + m_Offset;
    pos.setY(pos.y() + value);
    setPos(pos);
}

//-----------------------------------------------------------------------------
/**
** Sets a new value for the item. The value is shown as a number in the view.
**
** \param value The new value.
*/
void CNumberItem::setValue(int value)
{
    if (m_Value != value)
    {
        m_Value = value;
        update();
    }
}

//-----------------------------------------------------------------------------
/**
** Enables/disables the background for the item.
**
** \param bShow Set to true to display the background and false to hide it.
*/
void CNumberItem::showBackground(bool bShow)
{
    if (m_bShowBackground != bShow)
    {
        m_bShowBackground = bShow;
        update();
    }
}

//-----------------------------------------------------------------------------
/**
** Returns the bounding rect of the item. This is relative to the current position.
**
** \return The bounding rectangle.
*/
QRectF CNumberItem::boundingRect() const
{
    if (m_bReflection && CMainWindow::getPixmap(Pixmap_Flipped_Numbers))
    {
        return QRectF(0, 0, m_W, m_H * 1.5);
    }
    else
    {
        return QRectF(0, 0, m_W, m_H);
    }
}

//-----------------------------------------------------------------------------
/**
** Paints the number item with the given painter.
**
** \param pPainter The painter to be used.
** \param pOption The style options.
** \param pWidget The widget where the painting will be done.
*/
void CNumberItem::paint(QPainter* pPainter, const QStyleOptionGraphicsItem* pOption, QWidget* pWidget)
{
    Q_UNUSED(pOption);
    Q_UNUSED(pWidget);

    const QPixmap* pNumbers = CMainWindow::getPixmap(m_bDimmed ? Pixmap_Dimmed_Numbers : Pixmap_Numbers);
    const QPixmap* pFlippedNumbers = CMainWindow::getPixmap(Pixmap_Flipped_Numbers);

    if (pNumbers)
    {
        int numberHeight = pNumbers->size().height() / 11;
        int numberWidth = pNumbers->size().width();

        QPoint p(0, (m_H - numberHeight) / 2);
        if (m_bSeparator)
        {
            pPainter->drawPixmap(p, *pNumbers, QRectF(SEPARATOR_OFFSET, 10 * numberHeight, SEPARATOR_WIDTH, numberHeight));

            if (m_bReflection && pFlippedNumbers)
            {
                p += QPoint(0, numberHeight);
                pPainter->drawPixmap(p, *pFlippedNumbers, QRectF(SEPARATOR_OFFSET, 10 * numberHeight / 2, SEPARATOR_WIDTH, numberHeight / 2));
            }
        }
        else
        {
            if (m_bShowBackground)
            {
                // Background alpha depends on how far the item is from the center
                int value = 50 - abs(pos().y() + m_H / 2) / 7;
                value = qMax(0, value);
                QColor c = CMainWindow::getColor(Color_Background);
                if (CThemeManager::instance().hasBackground())
                {
                    c.setAlpha(value);
                }
                else
                {
                    if (c.value() > 128)
                    {
                        c.setHsv(c.hue(), c.saturation(), c.value() - value);
                        c = c.darker(100 + value);
                    }
                    else
                    {
                        c.setHsv(c.hue(), c.saturation(), c.value() + value);
//                        c = c.lighter(100 + value);
                    }
                }
                pPainter->fillRect(0, 0, m_W, m_H, c);
            }

            if (m_bReflection && pFlippedNumbers)
            {
                QPoint p2(p);
                p2 += QPoint(0, numberHeight);
                pPainter->drawPixmap(p2, *pFlippedNumbers, QRectF(0, (m_Value / 10) * numberHeight / 2, numberWidth, numberHeight / 2));
                pPainter->drawPixmap(p2 + QPoint(numberWidth, 0), *pFlippedNumbers, QRectF(0, (m_Value % 10) * numberHeight / 2, numberWidth, numberHeight / 2));
            }

            pPainter->drawPixmap(p, *pNumbers, QRectF(0, (m_Value / 10) * numberHeight, numberWidth, numberHeight));
            pPainter->drawPixmap(p + QPoint(numberWidth, 0), *pNumbers, QRectF(0, (m_Value % 10) * numberHeight, numberWidth, numberHeight));
        }
    }
}

//-----------------------------------------------------------------------------
/**
** Handler for the mouse move events. Forwards the event to the rotator.
**
** \param pEvent The mouse event.
*/
void CNumberItem::mouseMoveEvent(QGraphicsSceneMouseEvent* pEvent)
{
    if (m_pRotator)
    {
        pEvent->setPos(pEvent->pos() + pos());      // Map to scene coordinates
        m_pRotator->mouseMoveEvent(pEvent);
    }
}

//-----------------------------------------------------------------------------
/**
** Handler for the mouse press events. Forwards the event to the rotator.
**
** \param pEvent The mouse event.
*/
void CNumberItem::mousePressEvent(QGraphicsSceneMouseEvent* pEvent)
{
    if (m_pRotator)
    {
        pEvent->setPos(pEvent->pos() + pos());      // Map to scene coordinates
        m_pRotator->mousePressEvent(pEvent);
    }
}

//-----------------------------------------------------------------------------
/**
** Handler for the mouse release events. Forwards the event to the rotator.
**
** \param pEvent The mouse event.
*/
void CNumberItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* pEvent)
{
    if (m_pRotator)
    {
        pEvent->setPos(pEvent->pos() + pos());      // Map to scene coordinates
        m_pRotator->mouseReleaseEvent(pEvent);
    }
}

// EOF
